package com.tengju.data.infrastructure.repository.data.report;

import com.tengju.data.domain.model.analysis.Row;
import com.tengju.data.domain.model.report.performance.PerFormanceOrderType;
import com.tengju.data.domain.model.report.performance.ReportPerformanceRepository;
import com.tengju.data.domain.shared.Month;
import com.tengju.data.domain.shared.Quarter;
import com.tengju.data.domain.shared.Week;
import com.tengju.data.infrastructure.persistence.mybatis.mapper.data.custom.ReportPerformanceDdMMapper;
import com.tengju.data.infrastructure.persistence.mybatis.mapper.data.custom.ReportPerformanceIndexDdQMapper;
import com.tengju.data.infrastructure.persistence.mybatis.mapper.data.custom.ReportPerformanceIndexDdWMapper;
import com.tengju.data.infrastructure.persistence.mybatis.mapper.data.custom.ReportPerformanceIndexHdDMapper;
import com.tengju.user.domain.model.user.UserIdCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author chenhang
 * @Date 2021/8/23
 */
@Repository
@Slf4j
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class ReportPerformanceRepositoryImpl implements ReportPerformanceRepository {

    private final ReportPerformanceDdMMapper monthPerformanceMapper;
    private final ReportPerformanceIndexHdDMapper dayPerformanceMapper;
    private final ReportPerformanceIndexDdWMapper weekPerformanceMapper;
    private final ReportPerformanceIndexDdQMapper quarterPerformanceMapper;




    @Override
    public List<Row> getKaPerformanceDay(List<UserIdCode> genSecIdCodes, String date) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return Collections.emptyList();
        }
        List<Long> genSecIdCodeVals = genSecIdCodes.stream().map(v -> v.getValue()).collect(Collectors.toList());
        List<Map<String,Object>> result = dayPerformanceMapper.getSecPerformance(genSecIdCodeVals,date);
        if (CollectionUtils.isEmpty(result)) {
            return Collections.emptyList();
        }
        return result.stream()
                .map(Row::new)
                .collect(Collectors.toList());
    }

    @Override
    public List<Row> getKaPerformanceWeek(List<UserIdCode> genSecIdCodes, Week week) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return Collections.emptyList();
        }
        List<Long> genSecIdCodeVals = genSecIdCodes.stream().map(UserIdCode::getValue).collect(Collectors.toList());
        List<Map<String,Object>> result = weekPerformanceMapper.getSecPerformance(genSecIdCodeVals,week.getStartDate());
        if (CollectionUtils.isEmpty(result)) {
            return Collections.emptyList();
        }
        return result.stream()
                .map(Row::new)
                .collect(Collectors.toList());
    }

    @Override
    public List<Row> getKaPerformanceMonth(List<UserIdCode> genSecIdCodes, Month month) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return Collections.emptyList();
        }
        List<Long> genSecIdCodeVals = genSecIdCodes.stream().map(UserIdCode::getValue).collect(Collectors.toList());
        List<Map<String,Object>> result = monthPerformanceMapper.getSecPerformance(genSecIdCodeVals,month.getMonthInt());
        if (CollectionUtils.isEmpty(result)) {
            return Collections.emptyList();
        }
        return result.stream()
                .map(Row::new)
                .collect(Collectors.toList());
    }

    @Override
    public List<Row> getKaPerformanceQuarter(List<UserIdCode> genSecIdCodes, Quarter quarter) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return Collections.emptyList();
        }
        List<Long> genSecIdCodeVals = genSecIdCodes.stream().map(UserIdCode::getValue).collect(Collectors.toList());
        List<Map<String,Object>> result = quarterPerformanceMapper.getSecPerformance(genSecIdCodeVals,quarter.getQuarterStr());
        if (CollectionUtils.isEmpty(result)) {
            return Collections.emptyList();
        }
        return result.stream()
                .map(Row::new)
                .collect(Collectors.toList());
    }

    @Override
    public LocalDateTime getUpdateTimeDay(List<UserIdCode> genSecIdCodes, String date) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return null;
        }
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());
        return dayPerformanceMapper.getUpdateTime(date,idCodeList);
    }

    @Override
    public LocalDateTime getUpdateTimeWeek(List<UserIdCode> genSecIdCodes, Week week) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return null;
        }
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());
        return weekPerformanceMapper.getUpdateTime(week.getStartDate().toString(),
                week.getEndDate().toString(),
                idCodeList);
    }

    @Override
    public LocalDateTime getUpdateTimeMonth(List<UserIdCode> genSecIdCodes, Month month) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return null;
        }
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());
        return monthPerformanceMapper.getUpdateTime(month.getMonthInt(),idCodeList);
    }

    @Override
    public LocalDateTime getUpdateTimeQuarter(List<UserIdCode> genSecIdCodes, Quarter quarter) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return null;
        }
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());
        return quarterPerformanceMapper.getUpdateTime(quarter.getQuarterStr(),idCodeList);
    }

    @Override
    public List<Row> getSecAllTargetTableDay(List<UserIdCode> genSecIdCodes,
                                             String date,
                                             PerFormanceOrderType orderType,
                                             Integer offset, Integer limit) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return Collections.emptyList();
        }
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(idCodeList)) {
            return Collections.emptyList();
        }
        List<Map<String,Object>> result = dayPerformanceMapper.getSecAllTargetTable(date,
                idCodeList,
                orderType.getOrderColumn(),
                orderType.getOrderType(),
                offset,limit);
        if (CollectionUtils.isEmpty(result)) {
            return Collections.emptyList();
        }
        return result.stream()
                .map(Row::new)
                .collect(Collectors.toList());
    }

    @Override
    public List<Row> getSecAllTargetTableWeek(List<UserIdCode> genSecIdCodes,
                                              Week week,
                                              PerFormanceOrderType orderType,
                                              Integer offset, Integer limit) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return Collections.emptyList();
        }
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(idCodeList)) {
            return Collections.emptyList();
        }
        List<Map<String,Object>> result = weekPerformanceMapper.getSecAllTargetTable(week.getStartDate().toString(),
                week.getEndDate().toString(),
                idCodeList,
                orderType.getOrderColumn(),
                orderType.getOrderType(),
                offset,
                limit);
        if (CollectionUtils.isEmpty(result)) {
            return Collections.emptyList();
        }
        return result.stream()
                .map(Row::new)
                .collect(Collectors.toList());
    }

    @Override
    public List<Row> getSecAllTargetTableMonth(List<UserIdCode> genSecIdCodes,
                                               Month month,
                                               PerFormanceOrderType orderType,
                                               Integer offset, Integer limit) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return Collections.emptyList();
        }
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(idCodeList)) {
            return Collections.emptyList();
        }
        List<Map<String,Object>> result = monthPerformanceMapper.getSecAllTargetTable(month.getMonthInt(),
                idCodeList,
                orderType.getOrderColumn(),
                orderType.getOrderType(),
                offset,
                limit);
        if (CollectionUtils.isEmpty(result)) {
            return Collections.emptyList();
        }
        return result.stream()
                .map(Row::new)
                .collect(Collectors.toList());
    }

    @Override
    public List<Row> getSecAllTargetTableQuarter(List<UserIdCode> genSecIdCodes,
                                                 Quarter quarter,
                                                 PerFormanceOrderType orderType,
                                                 Integer offset, Integer limit) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return Collections.emptyList();
        }
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(idCodeList)) {
            return Collections.emptyList();
        }
        List<Map<String,Object>> result = quarterPerformanceMapper.getSecAllTargetTable(quarter.getQuarterStr(),
                idCodeList,
                orderType.getOrderColumn(),
                orderType.getOrderType(),
                offset,
                limit);
        if (CollectionUtils.isEmpty(result)) {
            return Collections.emptyList();
        }
        return result.stream()
                .map(Row::new)
                .collect(Collectors.toList());
    }

    @Override
    public Integer getSecAllTargetTableDayTotal(List<UserIdCode> genSecIdCodes, String date) {
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(idCodeList)) {
            return 0;
        }
        return dayPerformanceMapper.getSecAllTargetTableTotal(date,idCodeList);
    }

    @Override
    public Integer getSecAllTargetTableWeekTotal(List<UserIdCode> genSecIdCodes, Week week) {
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(idCodeList)) {
            return 0;
        }
        return weekPerformanceMapper.getSecAllTargetTableTotal(week.getStartDate().toString(),
                week.getEndDate().toString(),idCodeList);
    }

    @Override
    public Integer getSecAllTargetTableMonthTotal(List<UserIdCode> genSecIdCodes, Month month) {
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(idCodeList)) {
            return 0;
        }
        return monthPerformanceMapper.getSecAllTargetTableTotal(month.getMonthInt(),idCodeList);
    }

    @Override
    public Integer getSecAllTargetTableQuarterTotal(List<UserIdCode> genSecIdCodes, Quarter quarter) {
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(idCodeList)) {
            return 0;
        }
        return quarterPerformanceMapper.getSecAllTargetTableTotal(quarter.getQuarterStr(),idCodeList);
    }

    @Override
    public List<Row> getSecStarAllTargetTableDay(List<UserIdCode> genSecIdCodes,
                                                 String date,
                                                 PerFormanceOrderType orderType,
                                                 UserIdCode idCode, UserIdCode superIdCode, Integer offset, Integer limit) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return Collections.emptyList();
        }
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(idCodeList)) {
            return Collections.emptyList();
        }
        List<Map<String,Object>> result = dayPerformanceMapper.getSecStarAllTargetTable(date,
                idCode == null ? null : idCode.getValue(),
                idCodeList,
                superIdCode == null ? null : superIdCode.getValue(),
                orderType.getOrderColumn(),
                orderType.getOrderType(),
                offset,
                limit);
        if (CollectionUtils.isEmpty(result)) {
            return Collections.emptyList();
        }
        return result.stream()
                .map(Row::new)
                .collect(Collectors.toList());
    }

    @Override
    public List<Row> getSecStarAllTargetTableWeek(List<UserIdCode> genSecIdCodes,
                                                  Week week,
                                                  PerFormanceOrderType orderType,
                                                  UserIdCode idCode, UserIdCode superIdCode, Integer offset, Integer limit) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return Collections.emptyList();
        }
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(idCodeList)) {
            return Collections.emptyList();
        }
        List<Map<String,Object>> result = weekPerformanceMapper.getSecStarAllTargetTable(week.getStartDate().toString(),
                week.getEndDate().toString(),
                idCode == null ? null : idCode.getValue(),
                idCodeList,
                superIdCode == null ? null : superIdCode.getValue(),
                orderType.getOrderColumn(),
                orderType.getOrderType(),
                offset,
                limit);
        if (CollectionUtils.isEmpty(result)) {
            return Collections.emptyList();
        }
        return result.stream()
                .map(Row::new)
                .collect(Collectors.toList());
    }

    @Override
    public List<Row> getSecStarAllTargetTableMonth(List<UserIdCode> genSecIdCodes,
                                                   Month month,
                                                   PerFormanceOrderType orderType,
                                                   UserIdCode idCode, UserIdCode superIdCode, Integer offset, Integer limit) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return Collections.emptyList();
        }
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(idCodeList)) {
            return Collections.emptyList();
        }
        List<Map<String,Object>> result = monthPerformanceMapper.getSecStarAllTargetTable(month.getMonthInt(),
                idCode == null ? null : idCode.getValue(),
                idCodeList,
                superIdCode == null ? null : superIdCode.getValue(),
                orderType.getOrderColumn(),
                orderType.getOrderType(),
                offset,
                limit);
        if (CollectionUtils.isEmpty(result)) {
            return Collections.emptyList();
        }
        return result.stream()
                .map(Row::new)
                .collect(Collectors.toList());
    }

    @Override
    public List<Row> getSecStarAllTargetTableQuarter(List<UserIdCode> genSecIdCodes,
                                                     Quarter quarter,
                                                     PerFormanceOrderType orderType,
                                                     UserIdCode idCode, UserIdCode superIdCode, Integer offset, Integer limit) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return Collections.emptyList();
        }
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(idCodeList)) {
            return Collections.emptyList();
        }
        List<Map<String,Object>> result = quarterPerformanceMapper.getSecStarAllTargetTable(quarter.getQuarterStr(),
                idCode == null ? null : idCode.getValue(),
                idCodeList,
                superIdCode == null ? null : superIdCode.getValue(),
                orderType.getOrderColumn(),
                orderType.getOrderType(),
                offset,
                limit);
        if (CollectionUtils.isEmpty(result)) {
            return Collections.emptyList();
        }
        return result.stream()
                .map(Row::new)
                .collect(Collectors.toList());
    }

    @Override
    public Integer getSecStarAllTargetTableDayTotal(List<UserIdCode> genSecIdCodes, String date, UserIdCode idCode, UserIdCode superIdCode) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return 0;
        }
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(idCodeList)) {
            return 0;
        }
        return dayPerformanceMapper.getSecStarAllTargetTableTotal(date,
                idCode == null ? null : idCode.getValue(),
                idCodeList,
                superIdCode == null ? null : superIdCode.getValue());
    }

    @Override
    public Integer getSecStarAllTargetTableWeekTotal(List<UserIdCode> genSecIdCodes, Week week, UserIdCode idCode, UserIdCode superIdCode) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return 0;
        }
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(idCodeList)) {
            return 0;
        }
        return weekPerformanceMapper.getSecStarAllTargetTableTotal(week.getStartDate().toString(),
                week.getEndDate().toString(),
                idCode == null ? null : idCode.getValue(),
                idCodeList,
                superIdCode == null ? null : superIdCode.getValue());
    }

    @Override
    public Integer getSecStarAllTargetTableMonthTotal(List<UserIdCode> genSecIdCodes, Month month, UserIdCode idCode, UserIdCode superIdCode) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return 0;
        }
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(idCodeList)) {
            return 0;
        }
        return monthPerformanceMapper.getSecStarAllTargetTableTotal(month.getMonthInt(),
                idCode == null ? null : idCode.getValue(),
                idCodeList,
                superIdCode == null ? null : superIdCode.getValue());
    }

    @Override
    public Integer getSecStarAllTargetTableQuarterTotal(List<UserIdCode> genSecIdCodes, Quarter quarter, UserIdCode idCode, UserIdCode superIdCode) {
        if (CollectionUtils.isEmpty(genSecIdCodes)) {
            return 0;
        }
        List<Long> idCodeList = genSecIdCodes.stream()
                .filter(Objects::nonNull)
                .map(UserIdCode::getValue)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(idCodeList)) {
            return 0;
        }
        return quarterPerformanceMapper.getSecStarAllTargetTableTotal(quarter.getQuarterStr(),
                idCode == null ? null : idCode.getValue(),
                idCodeList,
                superIdCode == null ? null : superIdCode.getValue());
    }

    @Override
    public List<Row> getTopSecPerformanceDay(List<UserIdCode> secIdCodes, String date) {
        if (CollectionUtils.isEmpty(secIdCodes)) {
            return Collections.emptyList();
        }
        List<Long> genSecIdCodeVals = secIdCodes.stream().map(UserIdCode::getValue).collect(Collectors.toList());
        List<Map<String,Object>> result = dayPerformanceMapper.getTopSecPerformanceDay(genSecIdCodeVals,date);
        if (CollectionUtils.isEmpty(result)) {
            return Collections.emptyList();
        }
        return result.stream()
                .map(Row::new)
                .collect(Collectors.toList());
    }

    @Override
    public List<Row> getTopSecPerformanceWeek(List<UserIdCode> secIdCodes, Week week) {
        if (CollectionUtils.isEmpty(secIdCodes)) {
            return Collections.emptyList();
        }
        List<Long> genSecIdCodeVals = secIdCodes.stream().map(UserIdCode::getValue).collect(Collectors.toList());
        List<Map<String,Object>> result = weekPerformanceMapper.getTopSecPerformanceDay(genSecIdCodeVals,week.getStartDate());
        if (CollectionUtils.isEmpty(result)) {
            return Collections.emptyList();
        }
        return result.stream()
                .map(Row::new)
                .collect(Collectors.toList());
    }

    @Override
    public List<Row> getTopSecPerformanceMonth(List<UserIdCode> secIdCodes, Month month) {
        if (CollectionUtils.isEmpty(secIdCodes)) {
            return Collections.emptyList();
        }
        List<Long> genSecIdCodeVals = secIdCodes.stream().map(UserIdCode::getValue).collect(Collectors.toList());
        List<Map<String,Object>> result = monthPerformanceMapper.getTopSecPerformanceDay(genSecIdCodeVals,month.getMonthInt());
        if (CollectionUtils.isEmpty(result)) {
            return Collections.emptyList();
        }
        return result.stream()
                .map(Row::new)
                .collect(Collectors.toList());
    }

    @Override
    public List<Row> getTopSecPerformanceQuarter(List<UserIdCode> secIdCodes, Quarter quarter) {
        if (CollectionUtils.isEmpty(secIdCodes)) {
            return Collections.emptyList();
        }
        List<Long> genSecIdCodeVals = secIdCodes.stream().map(UserIdCode::getValue).collect(Collectors.toList());
        List<Map<String,Object>> result = quarterPerformanceMapper.getTopSecPerformanceDay(genSecIdCodeVals,quarter.getQuarterStr());
        if (CollectionUtils.isEmpty(result)) {
            return Collections.emptyList();
        }
        return result.stream()
                .map(Row::new)
                .collect(Collectors.toList());
    }
}
